<?php defined('BASEPATH') OR exit('No direct script access allowed');


/**
 * 后台权限资源管理
 */
class Resources extends Admin_Controller {


	public function __construct()
	{
		parent::__construct();

		$this->admin_path = APPPATH . "controllers/{$this->admin_dir_name}/";
	} 


	//列表页
	public function index()
	{
		$this->load->model('admin/resource_model', 'search_resource');

		//分页
        $data["pageCurrent"] = ForceIntFrom('pageCurrent');
        $data["pageSize"] = ForceIntFrom('pageSize');

        $data["pageCurrent"] = Iif($data["pageCurrent"], $data["pageCurrent"], 1);
        $data["pageSize"] = Iif($data["pageSize"], $data["pageSize"], 10);

		//排序
        $data["orderField"] = trim($this->input->post('orderField', true));
        $data["orderDirection"] = trim($this->input->post('orderDirection', true));

        $data["orderField"] = Iif($data["orderField"], $data["orderField"], 'id');
        $data["orderDirection"] = Iif($data["orderDirection"], $data["orderDirection"], 'desc');


		//搜索关键字等
        $data['keytype'] = trim($this->input->post('keytype', true));
        $data['keyword'] = trim($this->input->post('keyword', true));

        if(!empty($data['keyword']) && !empty($data['keytype']))
		{
            $this->search_resource->$data['keytype'] = $data['keyword'];
		}

		//获取记录列表
		$this->search_resource->_order_by = "adrc.{$data[orderField]} {$data[orderDirection]}";
        $this->search_resource->_page_index = $data["pageCurrent"];
        $this->search_resource->_page_count = $data["pageSize"];
		$this->search_resource->search();

        $data["list"] = $this->search_resource->_search_results;

		//获取总记录数
        $this->search_resource->_is_search_counter = true;
        $this->search_resource->search();

        $data["totalCount"] = $this->search_resource->_search_num_rows;


		$this->display('resources/index.html', $data);
	}


	//编辑权限资源
	public function edit($id = 0)
	{
		$this->add($id);
	}


	//添加或编辑权限资源
	//后台仅显示到admin目录下的第二级目录内的文件, 即：admin/aaa/bbb/xxxx.php
	public function add($id = 0)
	{
		$data['resource'] = null;
		$data['resources_list'] = null;

		$id = intval($id); //资源id

		//有id时加载资源 -- 编辑
		if($id)
		{
			$this->load->model('admin/resource_model', 'search_resource');
			
			if(!$this->search_resource->retrieve($id))
			{
				$this->error('权限资源不存在！');
			}

			//检测资源文件是否存在
			$file_path_relative = $this->search_resource->file_path; //资源文件路径(相对于后台管理admin目录)
			$file_path = $this->admin_path . $file_path_relative;

			if(!is_file($file_path))
			{
				$this->error('后台权限资源文件不存在！');
			}

			$public_functions = $this->get_public_functions($file_path); //public函数名数组

			if(empty($public_functions))
			{
				$this->error('所选文件无操作权限资源！');
			}

			$resources = unserialize($this->search_resource->resources);
			$resources_list = array();

			foreach($public_functions AS $key => $val)
			{
				$resources_list[$key]['func'] = $val;
				$resources_list[$key]['name'] = '';

				if(!empty($resources) AND isset($resources[$val]))
				{
					$resources_list[$key]['func'] = $val;
					$resources_list[$key]['name'] = $resources[$val];
				}
			}

			//赋值
			$data['resource'] = $this->search_resource;
			$data['resources_list'] = $resources_list;
			$data['resources_count'] = count($resources_list);
		}

		//读取目录树
		$admin_path_arr = $this->get_dir($this->admin_path); //后台仅显示到admin目录下的第二级目录内的文件, 即：admin/aaa/bbb/xxxx.php
		$data['admin_path_arr'] = $admin_path_arr;

		$this->display('resources/edit.html', $data);
	}


	//保存权限资源
	public function save()
	{
		$id = intval($_POST['id']); //资源id
		$source_name = trim($this->input->post('source_name', true)); //资源名称
		$file_path = trim($this->input->post('file_path', true)); //资源文件路径(相对于后台管理admin目录)

		$resources = $this->input->post('resources', true); //权限资源 -- 名称 数组

		if(!$file_path)
		{
			$this->error('未选择后台管理资源文件！');
		}

		if(!$source_name)
		{
			$this->error('请填写资源名称！');
		}

		if(empty($resources))
		{
			$this->error('所选后台文件无权限资源可添加！');
		}

		//检查每一个权限是否填写了名称
		foreach($resources AS $key => $val)
		{
			if(!$val)
			{
				$this->error('权限名称不能为空！');
			}
		}

		$this->load->model('admin/resource_model');

		$this->resource_model->file_path = $file_path;
		$this->resource_model->source_name = $source_name;
		$this->resource_model->resources = serialize($resources);

		if($id){ //更新数据

			$this->resource_model->_update_where = array('id' => $id);

			if($this->resource_model->update())
			{
				$this->success('权限资源 -> 更新成功！'); //编辑时不更新tab
			}

		}else{ //插入记录

			if($this->resource_model->insert())
			{
				$this->success('权限资源 -> 添加成功！', 'admin-resources-list'); //admin-resources-list指需要更新的tabId
			}
		}

		$this->error();
	}


	//删除权限资源
	public function delete($id = 0)
	{
		$id = intval($id); //资源id
		$delete_ids = trim($this->input->post('delete_ids', true)); //多id字符串 -- 批量删除, 如: 6,8,2

		if(empty($id) AND empty($delete_ids))
		{
			$this->error('未选择需要删除的后台管理资源！');
		}

		$this->load->model('admin/resource_model');


		if(!empty($id)){ //删除单记录

			$this->resource_model->_delete_where = array('id' => $id);

			if($this->resource_model->delete())
			{
				$this->success('权限资源 -> 删除成功！', 'admin-resources-list', false); //false表示: 不关闭当前tab或dialog
			}

		}elseif(!empty($delete_ids)){ //批量删除

			if($this->resource_model->delete_by_ids($delete_ids))
			{
				$this->success('权限资源 -> 批量删除成功！', 'admin-resources-list', false); //admin-resources-list指需要更新的tabId
			}
		}

		$this->error();
	}


	//ajax操作: 获取后台文件的权限资源
	public function ajax_get_source()
	{
		$this->load->model('bases/ajax');

		$status_is_ok = false;

		$file_path_relative = trim($this->input->post('file_path', true)); //资源文件路径(相对于后台管理admin目录)
		$file_path = $this->admin_path . $file_path_relative;

		if(!is_file($file_path))
		{
			$this->ajax->warnings = "未选择文件！";
		}
		else
		{
			$public_functions = $this->get_public_functions($file_path); //public函数名数组

			if(empty($public_functions))
			{
				$this->ajax->warnings = "所选文件无操作权限资源！";
			}
			else
			{
				$status_is_ok = true;

				$results = array('id' => '', 'source_name' => '', 'resources' => array());
				$resources = array();

				//查找是否存在记录
				$this->load->model('admin/resource_model', 'search_resource');

				if($this->search_resource->retrieve_by_file_path($file_path_relative))
				{
					$results['id'] = $this->search_resource->id;
					$results['source_name'] = $this->search_resource->source_name;

					$resources = unserialize($this->search_resource->resources);
				}

				foreach($public_functions AS $key => $val)
				{
					$results['resources'][$key]['func'] = strtolower($val);
					$results['resources'][$key]['name'] = '';

					if(!empty($resources) AND isset($resources[$val]))
					{
						$results['resources'][$key]['func'] = strtolower($val);
						$results['resources'][$key]['name'] = $resources[$val];
					}
				}

				$this->ajax->results = $results;
			}
		}


		if($status_is_ok){
			$this->ajax->status_code = Ajax::STATUS_CODE_SUCCESS;
		}else{
			$this->ajax->status_code = Ajax::STATUS_CODE_FAILED;
		}

		$this->ajax->render();
	}


    /**
     * 遍历目录, 仅选择php文件或文件夹, 且排除index.html, index.php, home.php, passport.php文件等(无权限设置)
     *
     * @param string $path_name 文件路径
     * @return array
     */
	private function get_dir($path_name)
	{
		$last = substr($path_name, -1);
		$path_name .= ($last == "/" OR $last == "\\") ? "" : "/";

		$dir_arr = array();

		foreach(glob($path_name . "*") as $key => $path)
		{
			$file_name = str_replace($path_name, '', $path);

			if(is_dir($path))
			{
				$dir_arr['1_' . $key]['filename'] = $file_name;
				$dir_arr['1_' . $key]['path'] = $this->get_dir($path);
			}
			elseif(!in_array($file_name, $this->no_method_auth_file_arr))
			{
				$dir_arr['2_' . $key]['filename'] = $file_name;
				$dir_arr['2_' . $key]['path'] = '';
			}
		}

		ksort($dir_arr); //按键名排序, 让文件夹排在前面
		$dir_arr = array_values($dir_arr); //去掉键名

		return $dir_arr;
	}


    /**
     * 获取文件的public类型的函数名称
     *
     * @param string $file_path 文件路径
     * @return array
     */
	private function get_public_functions($file_path)
	{
		$file_contents = file_get_contents($file_path);

		//仅匹配public类型的函数名称, 但不包含“_”或“ajax_”开头的函数名，不区分大小写
		preg_match_all('/public[\s]+function[\s]+((?!ajax_)[a-z]+\w+)[\s]*[\(]/msi', $file_contents, $matches);

		return $matches[1]; //public函数名数组
	}


}
